#include "FunctionNode.h"

#include "Output/Console.h"
#include "ScriptCompiler/Token/Token.h"
#include "ScriptCompiler/AST/TypeNode.h"
#include "ScriptCompiler/AST/AccessLevelNode.h"
#include "ScriptCompiler/AST/ParameterNode.h"
#include "ScriptCompiler/AST/SentenceBlockNode.h"
#include "ScriptCompiler/AST/ExpressionNode.h"
#include "ScriptCompiler/AST/DecoratorNode.h"
#include "ScriptCompiler/AST/FunctionContentNode.h"

void CFunctionNode::DebugPrint(int32_t InDepth)
{
    //print blank spaces for depth
    for(int32_t i=0;i<InDepth;i++)
    {
        WH::Print(U"\t");
    }

    //print access level
    if(AccessLevel.HasValue())
    {
        AccessLevel.GetValue()->DebugPrint(0);
        WH::Print(U" ");
    }

    if(Decorator.HasValue())
    {
        Decorator.GetValue()->DebugPrint(0);
        WH::Print(U" ");
    }

    //print return type
    ReturnType->DebugPrint(0);

    //print function name
    WH::Print(U" "+Name->ToString());

    //print parameters
    WH::Print(U"(");
    for(int i=0;i<Parameters.size();i++)
    {
        Parameters[i]->DebugPrint(0);
        if(i!=Parameters.size()-1)
        {
            WH::Print(U",");
        }
    }
    WH::Print(U")\n");

    

    if(Content.HasValue())
    {
        Content.GetValue()->DebugPrint(InDepth);
    }
    else
    {
        WH::Print(U";\n");
    }

}

std::shared_ptr<CScriptToken> CFunctionNode::GetFirstToken()
{
    if(AccessLevel.HasValue())
    {
        return AccessLevel.GetValue()->GetFirstToken();
    }
    else if(Decorator.HasValue())
    {
        return Decorator.GetValue()->GetFirstToken();
    }
    else
    {
        return ReturnType->GetFirstToken();
    }
}
